package com.coffee.order.service.sku.impl;

import java.util.Date;

import com.coffee.admin.service.common.bean.GtRegion;
import com.coffee.core.entity.Page;
import com.coffee.core.entity.PagerInfo;
import com.coffee.core.enums.ExceptionEnum;
import com.coffee.core.enums.SkuOrderStatusEnum;
import com.coffee.core.enums.SkuSalesInformationTypeEnum;
import com.coffee.core.exception.BusinessException;
import com.coffee.core.exception.ValidateBusinessException;
import com.coffee.core.util.BeanUtilExt;
import com.coffee.core.util.DTOUtils;
import com.coffee.core.util.StringUtil;
import com.coffee.order.api.sku.query.SkuOrderQuery;
import com.coffee.order.api.sku.req.HostRegionalSkuSalesInformationReq;
import com.coffee.order.api.sku.req.HostSkuSalesInformationReq;
import com.coffee.order.api.sku.result.PeriodizationSkuResult;
import com.coffee.order.api.sku.service.PeriodizationSkuService;
import com.coffee.order.service.sku.bean.EnjoyBeforePaySku;
import com.coffee.order.service.sku.bean.PeriodizationSku;
import com.coffee.order.service.sku.bean.RlSku;
import com.coffee.order.service.sku.bean.SkuOrder;
import com.coffee.order.service.sku.dao.PeriodizationSkuDao;
import com.coffee.order.service.sku.dao.SkuOrderDao;
import com.coffee.sku.api.sku.query.RegionalSkuSalesInformationQuery;
import com.coffee.sku.api.sku.query.SkuSalesInformationQuery;
import com.coffee.sku.api.sku.req.MerchantSkuListReq;
import com.coffee.sku.api.sku.req.SkuListReq;
import com.coffee.sku.api.sku.result.*;
import com.coffee.sku.service.sku.bean.*;
import com.coffee.sku.service.sku.dao.*;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;


@DubboService(dynamic = true)
public class PeriodizationSkuServiceImpl implements PeriodizationSkuService {
    @Resource
    private PeriodizationSkuDao periodizationSkuDao;
    @Resource
    private SkuOrderDao skuOrderDao;
    @Resource
    private SkuCategoryDao skuCategoryDao;
    @Resource
    private SkuSalesInformationDao skuSalesInformationDao;
    @Resource
    private RegionalSkuDao regionalSkuDao;
    @Resource
    private RegionalSkuSalesInformationDao regionalSkuSalesInformationDao;
    @Value("${cityId}")
    private String nationwideId;

    @Override
    public Page<PeriodizationSkuListResult> getPager(SkuListReq param, PagerInfo pr) {
        Page<PeriodizationSkuListResult> pager = new Page<PeriodizationSkuListResult>(pr.getStart(), pr.getPageSize());
        Integer count = periodizationSkuDao.count(param);
        pager.setTotalPage(count);
        if (count > 0) {
            List<PeriodizationSkuListResult> page = periodizationSkuDao.page(param, pr.getStart(), pr.getPageSize());
            for (PeriodizationSkuListResult skuListRep : page) {
                if (StringUtils.isNotEmpty(skuListRep.getPidPath())) {
                    String[] split = skuListRep.getPidPath().split(",");
                    SkuCategory skuCategory = skuCategoryDao.findById(Integer.parseInt(split[0]));
                    if (skuCategory != null) {
                        skuListRep.setCategoryName(skuCategory.getName());
                    }
                }
                Integer countRlSkuByHostSkuId = periodizationSkuDao.findCountRlSkuByHostSkuId(skuListRep.getSkuId());
                skuListRep.setViceCount(countRlSkuByHostSkuId);
                SkuOrderQuery skuOrderQuery = new SkuOrderQuery();
                skuOrderQuery.setSkuId(skuListRep.getSkuId());
                skuOrderQuery.setOrderType(SkuSalesInformationTypeEnum.PERIODIZATION.getCode());
                List<SkuOrder> list = skuOrderDao.list(skuOrderQuery);
                if (list.size() > 0) {
                    skuListRep.setIsCanDelete("N");
                }
            }
            pager.setData(page);
        }
        return pager;
    }


    @Override
    public List<MerchantSkuListResult> getMerchantSkuListResult(MerchantSkuListReq req) {
        Integer cityId = Integer.parseInt(nationwideId);
        if (req.getCityId().equals(cityId)) {
            return null;
        }
        List<MerchantSkuListResult> merchantSkuListResults = periodizationSkuDao.merchantSkuList(req);
        Integer skuIdsCount = regionalSkuSalesInformationDao.getSkuIdsCount(req);
        if (merchantSkuListResults != null && merchantSkuListResults.size() > 0) {
            Iterator<MerchantSkuListResult> iterator = merchantSkuListResults.iterator();
            while (iterator.hasNext()) {
                MerchantSkuListResult merchantSkuListRep = iterator.next();
                SkuSalesInformationQuery param = new SkuSalesInformationQuery();
                param.setSkuId(merchantSkuListRep.getId());
                SkuSalesInformation skuSalesInformationDaoFirst = skuSalesInformationDao.findFirst(param);
                merchantSkuListRep.setPrice(skuSalesInformationDaoFirst.getPrice());
                if (req.getCityId() != null && skuIdsCount > 0) {
                    RegionalSkuSalesInformationQuery regionalSkuSalesInformationQuery = new RegionalSkuSalesInformationQuery();
                    regionalSkuSalesInformationQuery.setGtRegionId(req.getCityId());
                    regionalSkuSalesInformationQuery.setSkuId(skuSalesInformationDaoFirst.getSkuId());
                    RegionalSkuSalesInformation regionalSkuSalesInformationDaoFirst = regionalSkuSalesInformationDao.findFirst(regionalSkuSalesInformationQuery);
                    if (regionalSkuSalesInformationDaoFirst != null) {
                        merchantSkuListRep.setPrice(regionalSkuSalesInformationDaoFirst.getRegionalPrice());
                    } else {
                        iterator.remove();
                    }
                }
            }
        }
        return merchantSkuListResults;
    }


    @Override
    public PeriodizationSkuDetailResult getDetail(Integer id) {
        SkuListReq skuListReq = new SkuListReq();
        skuListReq.setIsDelete("N");
        skuListReq.setSkuId(id);
        PeriodizationSkuDetailResult detail = periodizationSkuDao.getDetail(skuListReq);
        if (StringUtils.isNotEmpty(detail.getPidPath())) {
            String[] split = detail.getPidPath().split(",");
            SkuCategory skuCategory = skuCategoryDao.findById(Integer.parseInt(split[0]));
            if (skuCategory != null) {
                detail.setCategoryName(skuCategory.getName());
            }
        }
        SkuSalesInformationQuery skuSalesInformationQuery = new SkuSalesInformationQuery();
        skuSalesInformationQuery.setSkuId(id);
        skuSalesInformationQuery.setIsDelete("N");
        skuSalesInformationQuery.setType("periodization");
        List<SkuSalesInformation> list = skuSalesInformationDao.list(skuSalesInformationQuery);
        if (list.size() > 0) {
            List<SkuSalesInformationResult> skuSalesInformationResults = DTOUtils.convertList(list, SkuSalesInformationResult.class);
            detail.setSkuSalesInformationResults(skuSalesInformationResults);
        }
        List<PeriodizationRegionalSkuResult> periodizationRegionalSkuResult = regionalSkuSalesInformationDao.findPeriodizationRegionalSkuResult(null, id, null);
        detail.setPeriodizationRegionalSkuResults(periodizationRegionalSkuResult);
        List<PeriodizationViceSkuDetailResult> periodizationViceSkuDetailResults = periodizationSkuDao.viceSkuList(skuListReq);
        if (CollectionUtils.isNotEmpty(periodizationViceSkuDetailResults)) {
            for (PeriodizationViceSkuDetailResult periodizationViceSkuDetailResult : periodizationViceSkuDetailResults) {
                String[] split = periodizationViceSkuDetailResult.getPidPath().split(",");
                SkuCategory skuCategory = skuCategoryDao.findById(Integer.parseInt(split[0]));
                if (skuCategory != null) {
                    periodizationViceSkuDetailResult.setCategoryName(skuCategory.getName());
                }
                SkuSalesInformationQuery skuViceSalesInformationQuery = new SkuSalesInformationQuery();
                skuViceSalesInformationQuery.setSkuId(periodizationViceSkuDetailResult.getSkuId());
                skuViceSalesInformationQuery.setIsDelete("N");
                skuViceSalesInformationQuery.setType("periodization");
                skuViceSalesInformationQuery.setBelongSkuId(id);
                List<SkuSalesInformation> listVice = skuSalesInformationDao.list(skuViceSalesInformationQuery);
                if (listVice.size() > 0) {
                    List<SkuSalesInformationResult> skuViceSalesInformationResults = DTOUtils.convertList(listVice, SkuSalesInformationResult.class);
                    periodizationViceSkuDetailResult.setSkuSalesInformationResults(skuViceSalesInformationResults);
                }

                List<PeriodizationRegionalSkuResult> periodizationRegionalSkuResult1 = regionalSkuSalesInformationDao.findPeriodizationRegionalSkuResult(null, periodizationViceSkuDetailResult.getSkuId(), id);
                periodizationViceSkuDetailResult.setPeriodizationRegionalSkuResults(periodizationRegionalSkuResult1);
            }
        }
        detail.setPeriodizationViceSkuDetailResults(periodizationViceSkuDetailResults);
        return detail;
    }


    @Override
    public void delete(Integer id) {
        periodizationSkuDao.deleteById(id);
    }

    @Override
    public void deleteBySkuId(Integer id) {
        periodizationSkuDao.deleteBySkuId(id);
    }

    @Override
    public Integer add(PeriodizationSkuResult result) throws BusinessException {
        PeriodizationSku item = new PeriodizationSku();
        PeriodizationSku periodizationSku = periodizationSkuDao.findBySkuId(result.getSkuId());
        ValidateBusinessException.assertNull(periodizationSku, ExceptionEnum.ERROR_2000);
        Integer rlSkuvice = periodizationSkuDao.findRlSkuvice(result.getSkuId());
        ValidateBusinessException.assertFalse(rlSkuvice > 0, ExceptionEnum.ERROR_2001);
        BeanUtilExt.copyProperties(item, result);
        Integer insert = periodizationSkuDao.insert(item);
        return insert;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer update(PeriodizationSkuResult result) throws BusinessException {
        PeriodizationSku periodization = periodizationSkuDao.findBySkuId(result.getId());
        SkuOrderQuery skuOrderQuery = new SkuOrderQuery();
        skuOrderQuery.setSkuId(result.getId());
        skuOrderQuery.setTotalOrderType(SkuOrderStatusEnum.SUCCESS.getCode());
        List<SkuOrder> list = skuOrderDao.list(skuOrderQuery);
        ValidateBusinessException.assertCollectionEmpty(list,ExceptionEnum.ERROR_2012);
        PeriodizationSku periodizationSku = periodizationSkuDao.findBySkuId(result.getNewSkuId());
        ValidateBusinessException.assertNull(periodizationSku, ExceptionEnum.ERROR_2000);
        Integer rlSkuvice = periodizationSkuDao.findRlSkuvice(result.getNewSkuId());
        ValidateBusinessException.assertFalse(rlSkuvice > 0, ExceptionEnum.ERROR_2001);
        //删除之前的商品类型
        skuSalesInformationDao.deleteBySkuIdAndType(periodization.getSkuId(), SkuSalesInformationTypeEnum.PERIODIZATION.getCode());
        PeriodizationSku param = new PeriodizationSku();
        param.setId(periodization.getId());
        param.setSkuId(result.getNewSkuId());
        periodizationSkuDao.updateById(param);
        periodizationSkuDao.updateHostSkuId(periodization.getSkuId(), result.getNewSkuId());
        //删除规格
        skuSalesInformationDao.deleteBySkuIdAndType(result.getId(), SkuSalesInformationTypeEnum.PERIODIZATION.getCode());
        //删除区域配置
        regionalSkuSalesInformationDao.deleteBySkuId(result.getId(), SkuSalesInformationTypeEnum.PERIODIZATION.getCode(), null);
        return 1;
    }

    @Override
    public Integer updateIsEnable(Integer skuId, String isEnable) throws BusinessException {
        PeriodizationSku param = new PeriodizationSku();
        param.setSkuId(skuId);
        param.setIsEnable(isEnable);
        periodizationSkuDao.updateBySkuId(param);
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addBySkuIds(Integer hostSkuId, List<Integer> skuIds) throws BusinessException {
        List<Integer> existenceSkuIds = periodizationSkuDao.findSkuIds();
        List<Integer> viceSkuIds = periodizationSkuDao.findViceSkuIds(hostSkuId);
        Collection add = CollectionUtils.subtract(skuIds, viceSkuIds);
        Collection subtract = CollectionUtils.subtract(viceSkuIds, skuIds);
        List<Integer> subtractList = new ArrayList<>(subtract);
        periodizationSkuDao.deleteRlSkuByIds(subtractList, hostSkuId);
        //删除取消关联的副商品规格
        for (Integer integer : subtractList) {
            skuSalesInformationDao.deleteBySkuIdAndBelongSkuId(integer, hostSkuId);
        }
        List<Integer> addList = new ArrayList<>(add);
        if (addList.size() > 0) {
            List<RlSku> list = new ArrayList<>();
            for (Integer integer : addList) {
                boolean contains = existenceSkuIds.contains(integer);
                ValidateBusinessException.assertFalse(contains, ExceptionEnum.ERROR_2000);
                RlSku param = new RlSku();
                param.setViceSkuId(integer);
                param.setHostSkuId(hostSkuId);
                list.add(param);
            }
            periodizationSkuDao.insertRlSku(list);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteViceSku(Integer hostSkuId, Integer skuId) throws BusinessException {
        SkuSalesInformationQuery skuSalesInformationQuery = new SkuSalesInformationQuery();
        skuSalesInformationQuery.setSkuId(skuId);
        skuSalesInformationQuery.setBelongSkuId(hostSkuId);
        skuSalesInformationQuery.setType(SkuSalesInformationTypeEnum.PERIODIZATION.getCode());
        SkuSalesInformation skuSalesInformation = skuSalesInformationDao.findFirst(skuSalesInformationQuery);
        //删除副商品
        List<Integer> idList = new ArrayList<>();
        idList.add(skuId);
        periodizationSkuDao.deleteRlSkuByIds(idList, hostSkuId);
        //删除规格
        skuSalesInformationDao.deleteBySkuIdAndBelongSkuId(skuId, hostSkuId);
        if (skuSalesInformation != null) {
            //删除区域配置
            regionalSkuSalesInformationDao.deleteBySkuSalesInformationId(skuSalesInformation.getId());
        }

    }


    @Override
    public Map<Integer, PeriodizationSkuResult> getItemMap(Set<Integer> idSet) {
        Map<Integer, PeriodizationSkuResult> map = new HashMap<Integer, PeriodizationSkuResult>();
        List<PeriodizationSku> list = periodizationSkuDao.findByIds(StringUtil.setToList(idSet));
        List<PeriodizationSkuResult> resultList = DTOUtils.convertList(list, PeriodizationSkuResult.class);
        for (PeriodizationSkuResult item : resultList) {
            map.put(item.getId(), item);
        }
        return map;
    }

    @Override
    public Integer addHostSkuSalesInformation(HostSkuSalesInformationReq req) throws BusinessException {
        if (req.getHostSkuId() != null) {
            SkuSalesInformationQuery skuSalesInformationQuery = new SkuSalesInformationQuery();
            skuSalesInformationQuery.setSkuId(req.getSkuId());
            skuSalesInformationQuery.setBelongSkuId(req.getHostSkuId());
            skuSalesInformationQuery.setType(SkuSalesInformationTypeEnum.PERIODIZATION.getCode());
            SkuSalesInformation first = skuSalesInformationDao.findFirst(skuSalesInformationQuery);
            ValidateBusinessException.assertNull(first, ExceptionEnum.ERROR_2002);
        }
        SkuSalesInformation skuSalesInformation = new SkuSalesInformation();
        skuSalesInformation.setSkuId(req.getSkuId());
        skuSalesInformation.setProductName(req.getName());
        skuSalesInformation.setPrice(req.getPrice());
        skuSalesInformation.setSpecifications(req.getSpecifications());
        skuSalesInformation.setUnit(req.getUnit());
        skuSalesInformation.setStock(req.getStock());
        skuSalesInformation.setIsDelete("N");
        skuSalesInformation.setCreateTime(new Date());
        skuSalesInformation.setType(SkuSalesInformationTypeEnum.PERIODIZATION.getCode());
        skuSalesInformation.setBelongSkuId(req.getHostSkuId());
        Integer insert = skuSalesInformationDao.insert(skuSalesInformation);
        return insert;
    }

    @Override
    public Integer deleteHostSkuSalesInformation(Integer id, Integer hostSkuId) throws BusinessException {
        SkuOrderQuery skuOrderQuery = new SkuOrderQuery();
        skuOrderQuery.setSkuSalesInformationId(id);
        List<SkuOrder> list = skuOrderDao.list(skuOrderQuery);
        if (list.size() > 0) {
            throw BusinessException.build(ExceptionEnum.ERROR_2010);
        }
        List<PeriodizationRegionalSkuResult> periodizationRegionalSkuResult = regionalSkuSalesInformationDao.findPeriodizationRegionalSkuResult(id, null, hostSkuId);
        ValidateBusinessException.assertCollectionEmpty(periodizationRegionalSkuResult, ExceptionEnum.ERROR_2003);
        return skuSalesInformationDao.deleteById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addHostRegionalSkuSalesInformationReq(Integer skuId, List<HostRegionalSkuSalesInformationReq> reqs) throws BusinessException {
        RegionalSku regionalSku = regionalSkuDao.findBySkuId(skuId);
        if (regionalSku == null) {
            RegionalSku param = new RegionalSku();
            param.setSkuId(skuId);
            regionalSkuDao.insert(param);
        }
        List<RegionalSkuSalesInformation> regionalSkuSalesInformationList = getRegionalSkuSalesInformationList(skuId, reqs);
        regionalSkuSalesInformationDao.insertBatch(regionalSkuSalesInformationList);
    }

    @Override
    public void updateHostRegionalSkuSalesInformationReq(Integer hostSkuId, Integer skuId, List<HostRegionalSkuSalesInformationReq> reqs) throws BusinessException {
        PeriodizationSku periodizationSku = periodizationSkuDao.findBySkuId(skuId);
        if (periodizationSku != null) {
            regionalSkuSalesInformationDao.deleteBySkuId(skuId, SkuSalesInformationTypeEnum.PERIODIZATION.getCode(), null);
        } else {
            regionalSkuSalesInformationDao.deleteBySkuId(skuId, SkuSalesInformationTypeEnum.PERIODIZATION.getCode(), hostSkuId);
        }
        List<RegionalSkuSalesInformation> regionalSkuSalesInformationList = getRegionalSkuSalesInformationList(skuId, reqs);
        regionalSkuSalesInformationDao.insertBatch(regionalSkuSalesInformationList);
    }


    public List<RegionalSkuSalesInformation> getRegionalSkuSalesInformationList(Integer skuId, List<HostRegionalSkuSalesInformationReq> regionalSkuSalesInformationResults) {
        List<RegionalSkuSalesInformation> regionalSkuSalesInformationList = new ArrayList<>();
        for (HostRegionalSkuSalesInformationReq regionalSkuSalesInformationResult : regionalSkuSalesInformationResults) {
            List<Integer> gtRegionIds = regionalSkuSalesInformationResult.getGtRegionIds();
            for (Integer gtRegionId : gtRegionIds) {
                RegionalSkuSalesInformation regionalSkuSalesInformation = new RegionalSkuSalesInformation();
                regionalSkuSalesInformation.setSkuId(skuId);
                regionalSkuSalesInformation.setGtRegionId(gtRegionId);
                regionalSkuSalesInformation.setSkuSalesInformationId(regionalSkuSalesInformationResult.getSkuSalesInformationId());
                regionalSkuSalesInformation.setRegionalPrice(regionalSkuSalesInformationResult.getRegionalPrice());
                regionalSkuSalesInformation.setProportion(regionalSkuSalesInformationResult.getProportion());
                regionalSkuSalesInformation.setRemark(regionalSkuSalesInformationResult.getRemark());
                regionalSkuSalesInformation.setDepositDeduction(regionalSkuSalesInformationResult.getDepositDeduction());
                regionalSkuSalesInformation.setCycles(regionalSkuSalesInformationResult.getCycles());
                regionalSkuSalesInformationList.add(regionalSkuSalesInformation);
            }
        }
        Collections.reverse(regionalSkuSalesInformationList);
        ArrayList<RegionalSkuSalesInformation> collect = regionalSkuSalesInformationList.stream()
                .collect(Collectors.collectingAndThen(Collectors.toCollection(()
                        -> new TreeSet<>(Comparator.comparing(u -> u.getSkuSalesInformationId() + "#" + u.getGtRegionId()))), ArrayList::new));
        return collect;
    }


}
